package com.lifang.framework.aop.aspectj;

import com.lifang.framework.aop.framework.ReflectiveMethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.SourceLocation;
import org.aspectj.runtime.internal.AroundClosure;

public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, JoinPoint.StaticPart {

    private final ReflectiveMethodInvocation methodInvocation;

    private Signature signature;

    private SourceLocation sourceLocation;

    public MethodInvocationProceedingJoinPoint(ReflectiveMethodInvocation methodInvocation) {
        this.methodInvocation = methodInvocation;
    }

    @Override
    public int getId() {
        return 0;
    }

    @Override
    public void set$AroundClosure(AroundClosure arc) {
        throw new IllegalArgumentException("unsupported operation");
    }

    @Override
    public Object proceed() throws Throwable {
        return this.methodInvocation.proceed();
    }

    @Override
    public Object proceed(Object[] arguments) throws Throwable {
        if (arguments.length != this.methodInvocation.getArguments().length) {
            throw new IllegalArgumentException("Expecting " + this.methodInvocation.getArguments().length + " arguments to proceed, " +
                    "but was passed " + arguments.length + " arguments");
        }
        this.methodInvocation.setArguments(arguments);
        return this.methodInvocation.proceed();
    }

    @Override
    public String toShortString() {
        return null;
    }

    @Override
    public String toLongString() {
        return null;
    }

    @Override
    public Object getThis() {
        return this.methodInvocation.getThis();
    }

    @Override
    public Object getTarget() {
        return this.methodInvocation.getTarget();
    }

    @Override
    public Object[] getArgs() {
        return this.methodInvocation.getArguments();
    }

    @Override
    public Signature getSignature() {
        if (this.signature == null) {
            this.signature = new MethodSignatureImpl(methodInvocation);
        }
        return signature;
    }

    @Override
    public SourceLocation getSourceLocation() {
        throw new IllegalArgumentException("unsupported operation");
    }

    @Override
    public String getKind() {
        return "method-execution";
    }

    @Override
    public StaticPart getStaticPart() {
        return this;
    }
}
